package servico;

import java.util.ArrayList;
import java.util.List;

import persistencia.dao.GenericDAO;
import persistencia.entidades.Supervisor;
import util.EmailUtil;
import exceptions.EmailFormatoInvalidoException;

/**
 * Classe de serviço para entidades do tipo Supervisor.
 * 
 * @autho Maciel Melo
 * @since 20/11/2013
 */
@SuppressWarnings("javadoc")
public class SupervisorService {

    private final GenericDAO<Supervisor> dao;

    public SupervisorService() {
	dao = new GenericDAO<Supervisor>();
    }

    public SupervisorService(GenericDAO<Supervisor> dao) {
	this.dao = dao;
    }

    /* CRUD */
    public Supervisor salvaOuAtualiza(Supervisor entidade)
	    throws EmailFormatoInvalidoException {
	if (EmailUtil.isValido(entidade.getEmail()) && emailUnico(entidade)) {
	    return dao.insertOrUpdate(entidade);
	} else {
	    String msg = String
		    .format("Email: %s no formato inválido ou já existe um supervisor com esse email",
			    entidade.getEmail());
	    throw new EmailFormatoInvalidoException(msg);
	}
    }

    private Boolean emailUnico(Supervisor supervisor) {
	List<Supervisor> supervisores = dao.findAll(Supervisor.class, false);

	for (Supervisor entidade : supervisores) {
	    if (entidade.getEmail().equalsIgnoreCase(supervisor.getEmail())) {
		return false;
	    }
	}

	return true;
    }

    /**
     * Carregamento de todas as entidades supervisor em modo Lazy.
     */
    public List<Supervisor> buscarTodosLazy() {
	return dao.findAll(Supervisor.class, false);
    }

    /**
     * Carregamento de todas as entidades supervisor junto suas dependências
     */
    public List<Supervisor> buscarTodosIncluirDependências() {
	return dao.findAll(Supervisor.class, true);
    }

    /**
     * Busca uma entidade específica com todas as suas dependências carregadas.
     */
    public Supervisor buscarPorId(Long id) {
	return dao.findById(Supervisor.class, id, true);
    }

    /**
     * Retorna uma lista de entidades que o atributo nome contém a string nome
     * passada como parâmetro.</br> </br> Exemplo: paramentro = Maciel, retornos
     * válidos: Maciel Leite de Melo, MMaciel, MacielMelo.
     */
    public List<Supervisor> buscaPorNomeList(String nome) {
	List<Supervisor> listResultado = new ArrayList<Supervisor>();

	for (Supervisor entidade : dao.findAll(Supervisor.class, false)) {
	    if (entidade.getNome().contains(nome)) {
		listResultado.add(entidade);
	    }
	}
	return listResultado;
    }

    public Supervisor buscaPorNome(String nome) {

	for (Supervisor entidade : dao.findAll(Supervisor.class, false)) {
	    if (entidade.getNome().equals(nome)) {
		return entidade;
	    }
	}
	return null;
    }
}
